關注點分離實戰說明
- 使用關注點分離,完成 Todo List 的拆解觀念。
- 使用關注點分離的概念,將 HTML 轉為互動式結構。
- 使用關注點分離,將遠端資料渲染在畫面上。
實例連結
HTML
<div id="app" class="container my-3">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">待辦事項</span>
</div>
<!-- 輸入任務 -->
<input type="text" class="form-control" placeholder="準備要做的任務" id="newTodo">
<div class="input-group-append">
<button class="btn btn-primary" type="button" id="addTodo">新增</button>
</div>
</div>
<div class="card text-center">
<!-- 顯示任務 -->
<ul class="list-group list-group-flush text-left" id="todoList">
</ul>
<div class="card-footer d-flex justify-content-between">
<span>有 <span id="taskCount">0</span> 筆任務</span>
<a href="#" id="clearTask">清除所有任務</a>
</div>
</div>
</div>
JavaScript
//指定DOM
let newTask = document.getElementById('newTodo');
let addBtn = document.getElementById('addTodo');
let clearAllBtn = document.getElementById('clearTask');
let todoList = document.getElementById('todoList');
let countTask = document.getElementById('taskCount');
//監聽事件
addBtn.addEventListener('click', addTodo); //監聽新增todo按鍵
newTask.addEventListener('keypress', enterKey) //監聽按 Enter 新增資料
clearAllBtn.addEventListener('click', clearAllTask); //監聽刪除全部任務按鍵
todoList.addEventListener('click', doSomething); //監聽任務列表的按鍵(刪除/打勾)
//建立資料
let Data = []
renderPage(Data);
//新增資料
function addTodo() {
let newTodo = newTask.value.trim(); // trim可以移除前後的空白,避免輸入多於字元
if (newTask !== '') {
Data.push({
id: Math.floor(Date.now()),
text: newTodo,
completed: false,
});
newTask.value = '';
renderPage(Data);
}
}
//String.trim()方法用來去除字串前後的空白,此方法並不會改變原來的字串,而是傳回一個新的字串
//按 Enter 新增資料
function enterKey(e) {
if (e.keyCode == 13) {
addTodo()
}
}
//刪除資料
function removeTodo(id) {
let newIndex = 0;
Data.forEach((item, key) => {
if (id == item.id) {
newIndex = key;
}
})
Data.splice(newIndex, 1);
renderPage(Data);
}
//勾選打開
function completeTodo(id) {
Data.forEach((item) => {
if (id == item.id) {
item.completed = item.completed ?
flase : true;
}
})
}
//刪除全部資料
function clearAllTask(e) {
e.preventDefault();//預設行為無作用
Data = [];
renderPage(Data);
}
//任務列表的刪除/打勾動作
function doSomething(e) {
let action = e.target.parentNode.dataset.action; //點擊的動作
let id = e.target.parentNode.dataset.id; //點擊的ID
if (action == 'remove') {
removeTodo(id);
} else if (action == 'complete') {
completeTodo(id)
}
}
//把資料渲染到頁面上
function renderPage(data) {
let str = '';
data.forEach((item) => {
str += `<li class="list-group-item">
<div class="d-flex">
<div class="form-check" data-action="complete" data-id="${item.id}">
<input type="checkbox" class="form-check-input" ${item.completed ?
'checked' : ''}>
<label class="form-check-label ${item.completed ? 'completed' : ''}">
${item.text}
</label>
</div>
<button type="button" class="close ml-auto remove" aria-label="Close"
data-action="remove" data-id="${item.id}">
<span aria-hidden="true">×</span>
</button>
</div>
</li>
`;
})
todoList.innerHTML = str;
countTask.textContent = data.length;
}